// 这个interface要求传入两个泛型(我的state的类型限制, RooTState的接口)
import type { Module } from 'vuex';

import type { IRootState } from '../types';
import type { ILoginState } from './login-types';
import type { IAccount } from '@/service/login/type';
import {
  accountLoginRequest,
  requestUserInfoById,
  requestUserMenuByRoleId
} from '@/service/login/login';
import localCache from '@/utils/cache';
import router from '@/router';
import { mapMenusToRoutes, mapMenusToPermissions } from '@/utils/mapMenus';

// Module<ILoginState, IRootState>: 一个是自己state的interface, 一个root的state的interface
const loginModule: Module<ILoginState, IRootState> = {
  namespaced: true,
  state() {
    return {
      token: '',
      userInfo: {},
      userMenu: {},
      userBtnPermissions: []
    };
  },
  mutations: {
    changeToken(state, token: string) {
      state.token = token;
    },
    changeUserInfo(state, userInfo: any) {
      state.userInfo = userInfo;
    },
    changeUserMenu(state, userMenu: any) {
      state.userMenu = userMenu;

      // 动态注册路由
      // 1.发送请求拿到userMenu的时候就是生成路由(routes)的时候
      const routes = mapMenusToRoutes(userMenu);
      // 2.开始动态注册路由 将routes => router.main.child
      routes.forEach((route) => {
        router.addRoute('main', route);
      });

      // 得到用户按键的permission
      state.userBtnPermissions = mapMenusToPermissions(state.userMenu);
    }
  },
  actions: {
    async accountLoginAction({ commit, dispatch }, payload: IAccount) {
      // 1.登录逻辑
      const loginResult = await accountLoginRequest(payload); // 发送请求拿到用户登录的数据.返回的是一个promise
      const { id, token } = loginResult.data; // 将token与用户信息保存在store中
      commit('changeToken', token);
      localCache.setCache('token', token); // 将token储存在localStorage里面,用户下次不需要再登录.
      // 拦截器可以从localStorage中拿到token,拦截器每次发送请求都会将token放在请求头的.Authorization里

      // 发送初始化的请求(完整的role/department)
      dispatch('getDepartmentAndRoleListAction', null, { root: true });

      // 2.登录用户信息处理
      const userInfoResult = await requestUserInfoById(id);
      const userInfo = userInfoResult.data;
      commit('changeUserInfo', userInfo);
      localCache.setCache('userInfo', userInfo); // 自动登录后也可以自动加载用户已有的信息
      // console.log(userInfo);  // 新接口自带了userMenu

      // 3.根据用户角色获取用户菜单
      const userMenuResult = await requestUserMenuByRoleId(userInfo.role.id);
      const userMenu = userMenuResult.data;
      commit('changeUserMenu', userMenu);
      localCache.setCache('userMenu', userMenu);

      // 跳到首页.
      // 默认跳到主页,但是我们设置的导航守卫,只要不是去login页面就要验查看你是否有token
      router.push('/main');
    },
    /* phoneLoginAction({ commit }, payload: any) {
      console.log('in action phoneLoginAction');
    } */
    loadLocalLoginData({ commit, dispatch }) {
      const token = localCache.getCache('token');
      if (token) {
        commit('changeToken', token);
        // 发送初始化的请求(完整的role/department)
        dispatch('getDepartmentAndRoleListAction', null, { root: true });
      }
      const userInfo = localCache.getCache('userInfo');
      if (userInfo) {
        commit('changeUserInfo', userInfo);
      }
      const userMenu = localCache.getCache('userMenu');
      if (userMenu) {
        commit('changeUserMenu', userMenu);
      }
    }
  }
};

export default loginModule;
